home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xoct / xoct.c < prev    next >
C/C++ Source or Header  |  1996-02-05  |  12KB  |  421 lines

  1. /*
  2. # X-BASED OCTAHEDRON
  3. #
  4. #  xoct.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /*
  27.   Version 4: 94/05/31 Xt
  28.   Version 3: 93/04/01 Motif
  29.   Version 2: 92/01/29 XView
  30.   Version 1: 91/03/19 SunView
  31. */
  32.  
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #ifdef VMS
  36. #include <unixlib.h>
  37. #define getlogin cuserid
  38. #else
  39. #ifndef apollo
  40. #include <unistd.h>
  41. #endif
  42. #endif
  43. #include <X11/Intrinsic.h>
  44. #include <X11/StringDefs.h>
  45. #include <X11/Shell.h>
  46. #include <X11/cursorfont.h>
  47. #include "Oct.h"
  48. #include "oct.xbm"
  49.  
  50. #ifndef SCOREFILE
  51. #define SCOREFILE "/usr/games/lib/oct.scores"
  52. #endif
  53.  
  54. /* The following are in OctP.h also */
  55. #define MINOCTAS 1
  56. #define PERIOD3 3
  57. #define PERIOD4 4
  58. #define BOTH 5
  59. #define MAXMODES 3
  60.  
  61. #define MAXOCTAS 6
  62. #define MAXRECORD 32767
  63. #define MAXPROGNAME 80
  64. #define MAXNAME 256
  65.  
  66. static void Initialize();
  67. static void CallbackOct();
  68.  
  69. static void PrintRecord();
  70. static int HandleSolved();
  71. static void PrintState();
  72. static void ReadRecords();
  73. static void WriteRecords();
  74.  
  75. static Arg arg[5];
  76. static int octRecord[MAXMODES][2][MAXOCTAS - MINOCTAS + 2], movesDsp = 0;
  77. static char progDsp[64] = "xoct";
  78. static char recordDsp[16] = "INF";
  79. static char messageDsp[128] = "Welcome";
  80. static char titleDsp[256] = "";
  81. static int oldSize;
  82.  
  83. static void Usage()
  84. {
  85.   (void) fprintf(stderr, "usage: xoct\n");
  86.   (void) fprintf(stderr,
  87.     "\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
  88.   (void) fprintf(stderr,
  89.     "\t[-display [{host}]:[{vs}]] [-fg {color}] [-bg {color}]\n");
  90.   (void) fprintf(stderr,
  91.     "\t[-{border|bd} {color}] [-mono] [-{size {int} | sticky}]\n");
  92.   (void) fprintf(stderr,
  93.     "\t[-{mode {int} | both}] [-[no]orient] [-[no]practice]\n");
  94.   (void) fprintf(stderr,
  95.     "\t[-face{0|1|2|3|4|5|6|7} {color}]\n");
  96.   exit(1);
  97. }
  98.  
  99. static XrmOptionDescRec options[] = {
  100.   {"-fg",        "*oct.Foreground",    XrmoptionSepArg,    NULL},
  101.   {"-bg",        "*Background",        XrmoptionSepArg,    NULL},
  102.   {"-foreground",    "*oct.Foreground",    XrmoptionSepArg,    NULL},
  103.   {"-background",    "*Background",        XrmoptionSepArg,    NULL},
  104.   {"-border",        "*oct.pieceBorder",    XrmoptionSepArg,    NULL},
  105.   {"-bd",        "*oct.pieceBorder",    XrmoptionSepArg,    NULL},
  106.   {"-mono",        "*oct.mono",        XrmoptionNoArg,        "TRUE"},
  107.   {"-size",        "*oct.size",        XrmoptionSepArg,    NULL},
  108.   {"-sticky",        "*oct.sticky",        XrmoptionNoArg,        "FALSE"},
  109.   {"-mode",        "*oct.mode",        XrmoptionSepArg,    NULL},
  110.   {"-both",        "*oct.mode",        XrmoptionNoArg,        "4"},
  111.   {"-orient",        "*oct.orient",        XrmoptionNoArg,        "TRUE"},
  112.   {"-noorient",        "*oct.orient",        XrmoptionNoArg,        "FALSE"},
  113.   {"-practice",        "*oct.practice",    XrmoptionNoArg,        "TRUE"},
  114.   {"-nopractice",    "*oct.practice",    XrmoptionNoArg,        "FALSE"},
  115.   {"-face0",        "*oct.faceColor0",    XrmoptionSepArg,    NULL},
  116.   {"-face1",        "*oct.faceColor1",    XrmoptionSepArg,    NULL},
  117.   {"-face2",        "*oct.faceColor2",    XrmoptionSepArg,    NULL},
  118.   {"-face3",        "*oct.faceColor3",    XrmoptionSepArg,    NULL},
  119.   {"-face4",        "*oct.faceColor4",    XrmoptionSepArg,    NULL},
  120.   {"-face5",        "*oct.faceColor5",    XrmoptionSepArg,    NULL},
  121.   {"-face6",        "*oct.faceColor6",    XrmoptionSepArg,    NULL},
  122.   {"-face7",        "*oct.faceColor7",    XrmoptionSepArg,    NULL}
  123. };
  124.  
  125. int main(argc, argv)
  126.   int argc;
  127.   char *argv[];
  128. {
  129.   Widget toplevel, oct; 
  130.  
  131.   toplevel = XtInitialize(argv[0], "Oct",
  132.     options, XtNumber(options), &argc, argv);
  133.   if (argc != 1)
  134.     Usage();
  135.  
  136.   XtSetArg(arg[0], XtNiconPixmap,
  137.     XCreateBitmapFromData(XtDisplay(toplevel),
  138.       RootWindowOfScreen(XtScreen(toplevel)),
  139.       (char *) oct_bits, oct_width, oct_height));
  140.   XtSetValues(toplevel, arg, 1);
  141.   oct = XtCreateManagedWidget("oct", octWidgetClass, toplevel,
  142.     NULL, 0);
  143.   XtAddCallback(oct, XtNselectCallback, CallbackOct, NULL);
  144.   Initialize(oct);
  145.   XtRealizeWidget(toplevel);
  146.   XGrabButton(XtDisplay(oct), AnyButton, AnyModifier, XtWindow(oct),
  147.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  148.     GrabModeAsync, GrabModeAsync, XtWindow(oct),
  149.     XCreateFontCursor(XtDisplay(oct), XC_crosshair));
  150.   XtMainLoop();
  151.  
  152. #ifdef VMS
  153.   return 1;
  154. #else
  155.   return 0;
  156. #endif
  157. }
  158.  
  159. static void Initialize(w)
  160.   Widget w;
  161. {
  162.   int size, mode;
  163.   Boolean orient, sticky, practice;
  164.  
  165.   XtVaSetValues(w,
  166.     XtNstart, FALSE,
  167.     NULL);
  168.   XtVaGetValues(w,
  169.     XtNsize, &size,
  170.     XtNmode, &mode,
  171.     XtNorient, &orient,
  172.     XtNsticky, &sticky,
  173.     XtNpractice, &practice,
  174.     NULL);
  175.   ReadRecords();
  176.   PrintRecord(size, mode, orient, sticky, practice, recordDsp);
  177.   oldSize = size;
  178.   PrintState(XtParent(w), progDsp, mode, size, sticky, movesDsp,
  179.     recordDsp, messageDsp);
  180. }
  181.  
  182. static void CallbackOct(w, clientData, callData)
  183.   Widget w;
  184.   caddr_t clientData;
  185.   octCallbackStruct *callData;
  186. {
  187.   int size, mode;
  188.   Boolean orient, sticky, practice, start;
  189.  
  190.   XtVaGetValues(w,
  191.     XtNsize, &size,
  192.     XtNorient, &orient,
  193.     XtNmode, &mode,
  194.     XtNorient, &orient,
  195.     XtNsticky, &sticky,
  196.     XtNpractice, &practice,
  197.     XtNstart, &start,
  198.     NULL);
  199.   (void) strcpy(messageDsp, "");
  200.   switch (callData->reason) {
  201.     case OCT_RESTORE:
  202.       if (practice)
  203.         (void) strcpy(recordDsp, "practice");
  204.       movesDsp = 0;
  205.       break;
  206.     case OCT_RESET:
  207.       movesDsp = 0;
  208.       break;
  209.     case OCT_AMBIGUOUS:
  210.       (void) strcpy(messageDsp, "Ambiguous move");
  211.       break;
  212.     case OCT_ILLEGAL:
  213.       if (practice || start)
  214.         (void) strcpy(messageDsp, "Illegal move");
  215.       else
  216.         (void) strcpy(messageDsp, "Randomize to start");
  217.       break;
  218.     case OCT_MOVED:
  219.       movesDsp++;
  220. #ifdef DEBUG
  221.       if (movesDsp > 256)
  222.         exit(1);
  223. #endif
  224.       XtSetArg(arg[0], XtNstart, TRUE);
  225.       XtSetValues(w, arg, 1);
  226.       break;
  227.     case OCT_CONTROL:
  228.       return;
  229.     case OCT_SOLVED:
  230.       if (practice)
  231.         movesDsp = 0;
  232.       else { 
  233.         if (HandleSolved(movesDsp, size, mode, orient, sticky))
  234.           (void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
  235.         else
  236.           (void) strcpy(messageDsp, "Solved!");
  237.       }
  238.       XtSetArg(arg[0], XtNstart, FALSE);
  239.       XtSetValues(w, arg, 1);
  240.       break;
  241.     case OCT_PRACTICE:
  242.       movesDsp = 0;
  243.       practice = !practice;
  244.       if (!practice)
  245.         (void) strcpy(messageDsp, "Randomize to start");
  246.       PrintRecord(size, mode, orient, sticky, practice, recordDsp);
  247.       XtSetArg(arg[0], XtNpractice, practice);
  248.       XtSetArg(arg[1], XtNstart, FALSE);
  249.       XtSetValues(w, arg, 2);
  250.       break;
  251.     case OCT_RANDOMIZE:
  252.       movesDsp = 0;
  253.       XtSetArg(arg[0], XtNpractice, FALSE);
  254.       XtSetArg(arg[1], XtNstart, FALSE);
  255.       XtSetValues(w, arg, 2);
  256.       break; 
  257.     case OCT_DEC:
  258.       if (!sticky) {
  259.         movesDsp = 0;
  260.         size--;
  261.         oldSize = size;
  262.         PrintRecord(size, mode, orient, sticky, practice, recordDsp);
  263.         XtSetArg(arg[0], XtNsize, size);
  264.         XtSetValues(w, arg, 1);
  265.       }
  266.       break;
  267.     case OCT_ORIENT:
  268.       movesDsp = 0;
  269.       orient = !orient;
  270.       PrintRecord(size, mode, orient, sticky, practice, recordDsp);
  271.       XtSetArg(arg[0], XtNorient, orient);
  272.       XtSetValues(w, arg, 1);
  273.       break;
  274.     case OCT_INC:
  275.       if (!sticky) {
  276.         movesDsp = 0;
  277.         size++;
  278.         oldSize = size;
  279.         PrintRecord(size, mode, orient, sticky, practice, recordDsp);
  280.         XtSetArg(arg[0], XtNsize, size);
  281.         XtSetValues(w, arg, 1);
  282.       }
  283.       break;
  284.     case OCT_PERIOD3:
  285.     case OCT_PERIOD4:
  286.     case OCT_BOTH:
  287.       movesDsp = 0;
  288.       mode = callData->reason - OCT_PERIOD3 + PERIOD3;
  289.       PrintRecord(size, mode, orient, sticky, practice, recordDsp);
  290.       XtSetArg(arg[0], XtNmode, mode);
  291.       XtSetValues(w, arg, 1);
  292.       break;
  293.     case OCT_STICKY:
  294.       movesDsp = 0;
  295.       sticky = !sticky;
  296.       if (sticky)
  297.         size = 4;
  298.       else
  299.         size = oldSize;
  300.       PrintRecord(size, mode, orient, sticky, practice, recordDsp);
  301.       XtSetArg(arg[0], XtNsticky, sticky);
  302.       XtSetArg(arg[1], XtNsize, size);
  303.       XtSetValues(w, arg, 2);
  304.       break;
  305.     case OCT_COMPUTED:
  306.       XtSetArg(arg[0], XtNstart, FALSE);
  307.       XtSetValues(w, arg, 1);
  308.       break;
  309.     case OCT_UNDO:
  310.       movesDsp--;
  311.       XtSetArg(arg[0], XtNstart, TRUE);
  312.       XtSetValues(w, arg, 1);
  313.       break;
  314.   }
  315.   PrintState(XtParent(w), progDsp, mode, size, sticky, movesDsp,
  316.     recordDsp, messageDsp);
  317. }
  318.  
  319. static void PrintRecord(size, mode, orient, sticky, practice, record)
  320.   int size, mode;
  321.   Boolean orient, sticky, practice;
  322.   char *record;
  323. {
  324.   int i = mode - PERIOD3;
  325.   int j = (orient) ? 1 : 0;
  326.   int k = (sticky) ? MAXOCTAS - MINOCTAS + 1 : size - MINOCTAS;
  327.  
  328.   if (practice)
  329.     (void) strcpy(record, "practice");
  330.   else if (!sticky && size > MAXOCTAS)
  331.     (void) strcpy(record, "NOT RECORDED");
  332.   else if (octRecord[i][j][k] >= MAXRECORD)
  333.     (void) strcpy(record, "NEVER");
  334.   else
  335.     (void) sprintf(record, "%d", octRecord[i][j][k]);
  336. }
  337.  
  338. static int HandleSolved(counter, size, mode, orient, sticky)
  339.   int counter, size, mode;
  340.   Boolean orient, sticky;
  341. {
  342.   int i = mode - PERIOD3;
  343.   int j = (orient) ? 1 : 0;
  344.   int k = (sticky) ? MAXOCTAS - MINOCTAS + 1 : size - MINOCTAS;
  345.  
  346.   if ((sticky || size <= MAXOCTAS) && counter < octRecord[i][j][k]) {
  347.     octRecord[i][j][k] = counter;
  348.     if ((size < 2 && mode != PERIOD4) || (size < 4  && mode == PERIOD4) ||
  349.         (orient && (octRecord[i][j][k] < octRecord[i][!j][k])))
  350.       octRecord[i][!j][k] = counter;
  351.     WriteRecords();
  352.     (void) sprintf(recordDsp, "%d", counter);
  353.     return TRUE;
  354.   }
  355.   return FALSE;
  356. }
  357.  
  358. static void PrintState(w, prog, mode, size, sticky, moves, record, message)
  359.   Widget w;
  360.   char *prog, *record, *message;
  361.   int mode, size, moves;
  362.   Boolean sticky;
  363. {
  364.   char ss[10], mb[10];
  365.  
  366.   if (sticky)
  367.     (void) strcpy(ss, "sticky");
  368.   else
  369.     (void) sprintf(ss, "%d", size);
  370.   if (mode == BOTH)
  371.     (void) strcpy(mb, "both");
  372.   else
  373.     (void) sprintf(mb, "%d", mode);
  374.   (void) sprintf(titleDsp, "%s.%s: %s@ (%d/%s) - %s", prog, mb, ss, moves,
  375.     record, message);
  376.   XtSetArg(arg[0], XtNtitle, titleDsp);
  377.   XtSetValues(w, arg, 1);
  378. }
  379.  
  380. static void ReadRecords()
  381. {
  382.   FILE *fp;
  383.   int i, n, mode, orient;
  384.  
  385.   for (mode = 0; mode < MAXMODES; mode++)
  386.     for (orient = 0; orient < 2; orient++)
  387.       for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++)
  388.         octRecord[mode][orient][i] = MAXRECORD;
  389.   if ((fp = fopen(SCOREFILE, "r")) == NULL)
  390.     (void) sprintf(messageDsp, "Can not open %s, taking defaults.", SCOREFILE);
  391.   else {
  392.     for (mode = 0; mode < MAXMODES; mode++)
  393.       for (orient = 0; orient < 2; orient++)
  394.         for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++) {
  395.           (void) fscanf(fp, "%d", &n);
  396.           octRecord[mode][orient][i] = n;
  397.         }
  398.     (void) fclose(fp);
  399.   }
  400. }
  401.  
  402. static void WriteRecords()
  403. {
  404.   FILE *fp;
  405.   int i, mode, orient;
  406.  
  407.   if ((fp = fopen(SCOREFILE, "w")) == NULL)
  408.     (void) sprintf(messageDsp, "Can not write to %s.", SCOREFILE);
  409.   else {
  410.     for (mode = 0; mode < MAXMODES; mode++) {
  411.       for (orient = 0; orient < 2; orient++) {
  412.         for (i = 0; i <= MAXOCTAS - MINOCTAS + 1; i++)
  413.           (void) fprintf(fp, "%d ", octRecord[mode][orient][i]);
  414.         (void) fprintf(fp, "\n");
  415.       }
  416.       (void) fprintf(fp, "\n");
  417.     }
  418.     (void) fclose(fp);
  419.   }
  420. }
  421.